package cn.jsj.machine.service.impl;

import cn.jsj.machine.dao.IMachineDao;
import cn.jsj.machine.dao.IPartDao;
import cn.jsj.machine.exceptions.MyRuntimeIdentityException;
import cn.jsj.machine.exceptions.MyRuntimeParamsException;
import cn.jsj.machine.pojo.CMachine;
import cn.jsj.machine.pojo.CPart;
import cn.jsj.machine.service.MachineService;
import cn.jsj.machine.service.UserService;
import com.alibaba.fastjson.JSON;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

import static org.springframework.transaction.annotation.Isolation.REPEATABLE_READ;
import static org.springframework.transaction.annotation.Isolation.SERIALIZABLE;

@Service
public class MachineServiceImpl implements MachineService {

    @Autowired
    private IMachineDao machineDao;

    @Autowired
    private IPartDao partDao;

    @Autowired
    private UserService userService;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = SERIALIZABLE)
    public void resetMachineDescription(Integer account, String password, Integer machineID, String str) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("身份验证有误");
        }
        CMachine machine = this.machineDao.getOneMachineByID(machineID);
        if(machine == null){
            throw new MyRuntimeParamsException("产品信息不存在");
        }
        this.machineDao.resetDescriptionOfMachine(machine.getMachineID(),str.trim());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = SERIALIZABLE)
    public void deleteMachine(Integer account, String password, Integer machineID) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("身份验证有误");
        }
        CMachine machine = this.machineDao.getOneMachineByID(machineID);
        if(machine == null){
            throw new MyRuntimeParamsException("产品信息不存在");
        }
        this.machineDao.deletePartInformationOfMachine(machine.getMachineID());
        this.machineDao.deleteMachineInformation(machine.getMachineID());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = SERIALIZABLE)
    public void changePartNeedNumber(Integer account, String password, Integer machineID, Integer partID, Integer needNmb) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("身份验证有误");
        }
        Integer needNumber = this.machineDao.getPartNeedNumberOfMachine(machineID,partID);
        if(needNumber == null){
            throw new MyRuntimeParamsException("参数有误");
        }
        CPart part = this.partDao.getOnePartByID(partID);
        if(needNmb > needNumber){
            this.machineDao.addMachineValue(machineID,(needNmb - needNumber)* part.getRmb());
        }else{
            if(needNmb < needNumber){
                this.machineDao.reduceMachineValue(machineID,(needNumber-needNmb)*part.getRmb());
            }else{
                throw new MyRuntimeParamsException("产品包含数量没有改变");
            }
        }
        this.machineDao.changeNeedNumber(machineID,part.getPartID(),needNmb);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public List<CPart> getOneMachineParts(Integer account, String password, Integer mechineID) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("身份验证有误");
        }
        return this.partDao.getPartListOfMachine(mechineID);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public void addOnePartToMachine(Integer account, String password,Integer machineID, Integer partID, Integer number, boolean checkMachine, boolean checkPart,boolean checiIdentity){
        if(checiIdentity == true){
            Integer i = this.userService.userLogin(account, password);
            if(i == -1){
                throw new MyRuntimeIdentityException("用户身份错误");
            }
        }
        if(checkMachine == true){
            CMachine machine = this.machineDao.getOneMachineByID(machineID);
            if(machine == null){
                throw new MyRuntimeParamsException("产品信息有误");
            }
        }
        if(checkPart == true){
            CPart part = this.partDao.getOnePartByID(partID);
            if(part == null){
                throw new MyRuntimeParamsException("零部件信息有误");
            }
        }
        Integer needNumber = this.machineDao.getPartNeedNumberOfMachine(machineID,partID);
        if(needNumber != null){
            throw new MyRuntimeParamsException("该机型已存在该配件信息，无需重复添加");
        }
        this.machineDao.addOnePartOfMachine(machineID,partID,number);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public void addOnePartToMachineWithPartName(Integer account, String password, Integer machineID, String partName, Integer needNumber) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("身份验证有误");
        }
        CMachine machine = this.machineDao.getOneMachineByID(machineID);
        CPart part = this.partDao.getOnePartByName(partName.trim());
        if(part == null){
            throw new MyRuntimeParamsException("您的配件列表中暂无此项，请检查名称是否输入正确，或该配件是否加入配件列表");
        }
        if(machine == null){
            throw new MyRuntimeParamsException("参数有误");
        }
        Integer nNumber = this.machineDao.getPartNeedNumberOfMachine(machineID,part.getPartID());
        if(nNumber != null){
            throw new MyRuntimeParamsException("该机型已存在该配件信息，无需重复添加");
        }
        this.machineDao.addMachineValue(machine.getMachineID(),part.getRmb() * needNumber);
        this.machineDao.addOnePartOfMachine(machineID,part.getPartID(),needNumber);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public Integer insertOneMachine(Integer account, String password,String machineName, Map<Integer,Integer> partList) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("身份验证有误");
        }
        Integer keys = 0;
        CMachine machine = this.machineDao.getOneMachineByMachineName(machineName.trim());
        if(machine == null){
            keys = 1;
            machine = new CMachine();
            machine.setMachineName(machineName.trim());
            this.machineDao.addOneMachine(machine);
        }
        for(Integer j:partList.keySet()){
            CPart part = this.partDao.getOnePartByID(j);
            if(part == null){
                throw new MyRuntimeParamsException("参数错误，添加失败");
            }
            this.machineDao.addMachineValue(machine.getMachineID(),part.getRmb()*partList.get(j));
            this.addOnePartToMachine(account,password,machine.getMachineID(),j,partList.get(j),false,false,false);
        }
        return keys;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public List<CMachine> getMachineList(Integer account, String password) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("身份验证有误");
        }
        return this.machineDao.getAllOfMachines();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public void deleteOnePartFromMachine(Integer account, String password, Integer machineID, Integer partID) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("身份验证有误");
        }
        Integer needNum = this.machineDao.getPartNeedNumberOfMachine(machineID,partID);
        if(needNum == null){
            throw new MyRuntimeParamsException("参数有误");
        }
        CPart part = this.partDao.getOnePartByID(partID);
        if(part == null){
            throw new MyRuntimeParamsException("参数有误");
        }
        this.machineDao.reduceMachineValue(machineID,needNum * part.getRmb());
        this.machineDao.deleteOnePartInformationOfMachine(machineID,part.getPartID());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = SERIALIZABLE)
    public void productOneMachine(Integer account, String password, Integer machineID, Integer cutNumber) {
        List<CPart> parts = this.getOneMachineParts(account,password,machineID);
        if(parts == null || parts.size() == 0){
            throw new MyRuntimeParamsException("没有可扣除零件");
        }
        StringBuffer sb = new StringBuffer("");
        for(CPart i: parts){
            if(i.getRequreNumber()*cutNumber>i.getRemaining()){
                sb.append(i.getPartName()+",");
            }
        }
        if(sb.length()>0){
            String inf = sb.toString().trim();
            throw new MyRuntimeParamsException(inf+"库存不足，无法扣除库存量");
        }
        for(CPart i:parts){
            Integer j = this.partDao.cutNumberOfPart(i.getPartID(),i.getRequreNumber()*cutNumber);
            if(j != 1){
                throw new MyRuntimeParamsException("发生错误");
            }
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = REPEATABLE_READ)
    public void machineReName(Integer account, String password, Integer machineID, String newName) {
        Integer i = this.userService.userLogin(account, password);
        if(i == -1){
            throw new MyRuntimeIdentityException("身份验证有误");
        }
        CMachine machine = this.machineDao.getOneMachineByID(machineID);
        if(machine == null){
            throw new MyRuntimeParamsException("产品信息不存在");
        }
        CMachine machinec = this.machineDao.getOneMachineByMachineName(newName.trim());
        if(machinec != null){
            throw new MyRuntimeParamsException("修改失败，已存在该名称产品");
        }
        this.machineDao.renameOfMachine(machineID,newName);
    }
}
